home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / AWTEventMulticaster.java < prev    next >
Text File  |  1998-09-22  |  22KB  |  653 lines

  1. /*
  2.  * @(#)AWTEventMulticaster.java    1.13 98/07/01
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.event.*;
  17. import java.util.EventListener;
  18. import java.io.Serializable;
  19. import java.io.ObjectOutputStream;
  20. import java.io.IOException;
  21.  
  22.  
  23. /**
  24.  * A class which implements efficient and thread-safe multi-cast event 
  25.  * dispatching for the AWT events defined in the java.awt.event package.  
  26.  * This class will manage an immutable structure consisting of a chain of 
  27.  * event listeners and will dispatch events to those listeners.  Because
  28.  * the structure is immutable, it is safe to use this API to add/remove
  29.  * listeners during the process of an event dispatch operation.
  30.  *
  31.  * An example of how this class could be used to implement a new
  32.  * component which fires "action" events:
  33.  *
  34.  * <pre><code>
  35.  * public myComponent extends Component {
  36.  *     ActionListener actionListener = null;
  37.  *
  38.  *     public void addActionListener(ActionListener l) {
  39.  *       actionListener = AWTEventMulticaster.add(actionListener, l);
  40.  *     }
  41.  *     public void removeActionListener(ActionListener l) {
  42.  *         actionListener = AWTEventMulticaster.remove(actionListener, l);
  43.  *     }
  44.  *     public void processEvent(AWTEvent e) {
  45.  *         // when event occurs which causes "action" semantic
  46.  *         if (actionListener != null) {
  47.  *             actionListener.actionPerformed(new ActionEvent());
  48.  *         }         
  49.  * }
  50.  * </code></pre>
  51.  *
  52.  * @version     1.13, 07/01/98
  53.  * @author      John Rose
  54.  * @author     Amy Fowler
  55.  */
  56.  
  57. public class AWTEventMulticaster implements 
  58.     ComponentListener, ContainerListener, FocusListener, KeyListener,
  59.     MouseListener, MouseMotionListener, WindowListener,
  60.     ActionListener, ItemListener, AdjustmentListener,
  61.     TextListener {
  62.  
  63.     protected final EventListener a, b;
  64.  
  65.     /**
  66.      * Creates an event multicaster instance which chains listener-a
  67.      * with listener-b.
  68.      * @param a listener-a
  69.      * @param b listener-b
  70.      */ 
  71.     protected AWTEventMulticaster(EventListener a, EventListener b) {
  72.     this.a = a; this.b = b;
  73.     }
  74.  
  75.     /**
  76.      * Removes a listener from this multicaster and returns the
  77.      * resulting multicast listener.
  78.      * @param oldl the listener to be removed
  79.      */
  80.     protected EventListener remove(EventListener oldl) {
  81.     if (oldl == a)  return b;
  82.     if (oldl == b)  return a;
  83.     EventListener a2 = removeInternal(a, oldl);
  84.     EventListener b2 = removeInternal(b, oldl);
  85.     if (a2 == a && b2 == b) {
  86.         return this;    // it's not here
  87.     }
  88.     return addInternal(a2, b2);
  89.     }
  90.  
  91.     /**
  92.      * Handles the componentResized event by invoking the
  93.      * componentResized methods on listener-a and listener-b.
  94.      * @param e the component event
  95.      */
  96.     public void componentResized(ComponentEvent e) {
  97.         ((ComponentListener)a).componentResized(e);
  98.         ((ComponentListener)b).componentResized(e);
  99.     }
  100.  
  101.     /**
  102.      * Handles the componentMoved event by invoking the
  103.      * componentMoved methods on listener-a and listener-b.
  104.      * @param e the component event
  105.      */
  106.     public void componentMoved(ComponentEvent e) {
  107.         ((ComponentListener)a).componentMoved(e);
  108.         ((ComponentListener)b).componentMoved(e);
  109.     }
  110.  
  111.     /**
  112.      * Handles the componentShown event by invoking the
  113.      * componentShown methods on listener-a and listener-b.
  114.      * @param e the component event
  115.      */
  116.     public void componentShown(ComponentEvent e) {
  117.         ((ComponentListener)a).componentShown(e);
  118.         ((ComponentListener)b).componentShown(e);
  119.     }
  120.  
  121.     /**
  122.      * Handles the componentHidden event by invoking the
  123.      * componentHidden methods on listener-a and listener-b.
  124.      * @param e the component event
  125.      */
  126.     public void componentHidden(ComponentEvent e) {
  127.         ((ComponentListener)a).componentHidden(e);
  128.         ((ComponentListener)b).componentHidden(e);
  129.     }
  130.  
  131.     /**
  132.      * Handles the componentAdded container event by invoking the
  133.      * componentAdded methods on listener-a and listener-b.
  134.      * @param e the component event
  135.      */
  136.     public void componentAdded(ContainerEvent e) {
  137.         ((ContainerListener)a).componentAdded(e);
  138.         ((ContainerListener)b).componentAdded(e);
  139.     }
  140.  
  141.     /**
  142.      * Handles the componentRemoved container event by invoking the
  143.      * componentRemoved methods on listener-a and listener-b.
  144.      * @param e the component event
  145.      */
  146.     public void componentRemoved(ContainerEvent e) {
  147.         ((ContainerListener)a).componentRemoved(e);
  148.         ((ContainerListener)b).componentRemoved(e);
  149.     }
  150.  
  151.     /**
  152.      * Handles the focusGained event by invoking the
  153.      * focusGained methods on listener-a and listener-b.
  154.      * @param e the focus event
  155.      */
  156.     public void focusGained(FocusEvent e) {
  157.         ((FocusListener)a).focusGained(e);
  158.         ((FocusListener)b).focusGained(e);
  159.     }
  160.  
  161.     /**
  162.      * Handles the focusLost event by invoking the
  163.      * focusLost methods on listener-a and listener-b.
  164.      * @param e the focus event
  165.      */
  166.     public void focusLost(FocusEvent e) {
  167.         ((FocusListener)a).focusLost(e);
  168.         ((FocusListener)b).focusLost(e);
  169.     }
  170.  
  171.     /**
  172.      * Handles the keyTyped event by invoking the
  173.      * keyTyped methods on listener-a and listener-b.
  174.      * @param e the key event
  175.      */
  176.     public void keyTyped(KeyEvent e) {
  177.         ((KeyListener)a).keyTyped(e);
  178.         ((KeyListener)b).keyTyped(e);
  179.     }
  180.  
  181.     /**
  182.      * Handles the keyPressed event by invoking the
  183.      * keyPressed methods on listener-a and listener-b.
  184.      * @param e the key event
  185.      */
  186.     public void keyPressed(KeyEvent e) {
  187.         ((KeyListener)a).keyPressed(e);
  188.         ((KeyListener)b).keyPressed(e);
  189.     }
  190.  
  191.     /**
  192.      * Handles the keyReleased event by invoking the
  193.      * keyReleased methods on listener-a and listener-b.
  194.      * @param e the key event
  195.      */
  196.     public void keyReleased(KeyEvent e) {
  197.         ((KeyListener)a).keyReleased(e);
  198.         ((KeyListener)b).keyReleased(e);
  199.     }
  200.  
  201.     /**
  202.      * Handles the mouseClicked event by invoking the
  203.      * mouseClicked methods on listener-a and listener-b.
  204.      * @param e the mouse event
  205.      */
  206.     public void mouseClicked(MouseEvent e) {
  207.         ((MouseListener)a).mouseClicked(e);
  208.         ((MouseListener)b).mouseClicked(e);
  209.     }
  210.  
  211.     /**
  212.      * Handles the mousePressed event by invoking the
  213.      * mousePressed methods on listener-a and listener-b.
  214.      * @param e the mouse event
  215.      */
  216.     public void mousePressed(MouseEvent e) {
  217.         ((MouseListener)a).mousePressed(e);
  218.         ((MouseListener)b).mousePressed(e);
  219.     }
  220.  
  221.     /**
  222.      * Handles the mouseReleased event by invoking the
  223.      * mouseReleased methods on listener-a and listener-b.
  224.      * @param e the mouse event
  225.      */
  226.     public void mouseReleased(MouseEvent e) {
  227.         ((MouseListener)a).mouseReleased(e);
  228.         ((MouseListener)b).mouseReleased(e);
  229.     }
  230.  
  231.     /**
  232.      * Handles the mouseEntered event by invoking the
  233.      * mouseEntered methods on listener-a and listener-b.
  234.      * @param e the mouse event
  235.      */
  236.     public void mouseEntered(MouseEvent e) {
  237.         ((MouseListener)a).mouseEntered(e);
  238.         ((MouseListener)b).mouseEntered(e);
  239.     }
  240.  
  241.     /**
  242.      * Handles the mouseExited event by invoking the
  243.      * mouseExited methods on listener-a and listener-b.
  244.      * @param e the mouse event
  245.      */
  246.     public void mouseExited(MouseEvent e) {
  247.         ((MouseListener)a).mouseExited(e);
  248.         ((MouseListener)b).mouseExited(e);
  249.     }
  250.  
  251.     /**
  252.      * Handles the mouseDragged event by invoking the
  253.      * mouseDragged methods on listener-a and listener-b.
  254.      * @param e the mouse event
  255.      */
  256.     public void mouseDragged(MouseEvent e) {
  257.         ((MouseMotionListener)a).mouseDragged(e);
  258.         ((MouseMotionListener)b).mouseDragged(e);
  259.     }
  260.  
  261.     /**
  262.      * Handles the mouseMoved event by invoking the
  263.      * mouseMoved methods on listener-a and listener-b.
  264.      * @param e the mouse event
  265.      */
  266.     public void mouseMoved(MouseEvent e) {
  267.         ((MouseMotionListener)a).mouseMoved(e);
  268.         ((MouseMotionListener)b).mouseMoved(e);
  269.     }
  270.  
  271.     /**
  272.      * Handles the windowOpened event by invoking the
  273.      * windowOpened methods on listener-a and listener-b.
  274.      * @param e the window event
  275.      */
  276.     public void windowOpened(WindowEvent e) {
  277.         ((WindowListener)a).windowOpened(e);
  278.         ((WindowListener)b).windowOpened(e);
  279.     }
  280.  
  281.     /**
  282.      * Handles the windowClosing event by invoking the
  283.      * windowClosing methods on listener-a and listener-b.
  284.      * @param e the window event
  285.      */
  286.     public void windowClosing(WindowEvent e) {
  287.         ((WindowListener)a).windowClosing(e);
  288.         ((WindowListener)b).windowClosing(e);
  289.     }
  290.  
  291.     /**
  292.      * Handles the windowClosed event by invoking the
  293.      * windowClosed methods on listener-a and listener-b.
  294.      * @param e the window event
  295.      */
  296.     public void windowClosed(WindowEvent e) {
  297.         ((WindowListener)a).windowClosed(e);
  298.         ((WindowListener)b).windowClosed(e);
  299.     }
  300.  
  301.     /**
  302.      * Handles the windowIconified event by invoking the
  303.      * windowIconified methods on listener-a and listener-b.
  304.      * @param e the window event
  305.      */
  306.     public void windowIconified(WindowEvent e) {
  307.         ((WindowListener)a).windowIconified(e);
  308.         ((WindowListener)b).windowIconified(e);
  309.     }
  310.  
  311.     /**
  312.      * Handles the windowDeiconfied event by invoking the
  313.      * windowDeiconified methods on listener-a and listener-b.
  314.      * @param e the window event
  315.      */
  316.     public void windowDeiconified(WindowEvent e) {
  317.         ((WindowListener)a).windowDeiconified(e);
  318.         ((WindowListener)b).windowDeiconified(e);
  319.     }
  320.  
  321.     /**
  322.      * Handles the windowActivated event by invoking the
  323.      * windowActivated methods on listener-a and listener-b.
  324.      * @param e the window event
  325.      */
  326.     public void windowActivated(WindowEvent e) {
  327.         ((WindowListener)a).windowActivated(e);
  328.         ((WindowListener)b).windowActivated(e);
  329.     }
  330.  
  331.     /**
  332.      * Handles the windowDeactivated event by invoking the
  333.      * windowDeactivated methods on listener-a and listener-b.
  334.      * @param e the window event
  335.      */
  336.     public void windowDeactivated(WindowEvent e) {
  337.         ((WindowListener)a).windowDeactivated(e);
  338.         ((WindowListener)b).windowDeactivated(e);
  339.     }
  340.  
  341.     /**
  342.      * Handles the actionPerformed event by invoking the
  343.      * actionPerformed methods on listener-a and listener-b.
  344.      * @param e the action event
  345.      */
  346.     public void actionPerformed(ActionEvent e) {
  347.         ((ActionListener)a).actionPerformed(e);
  348.         ((ActionListener)b).actionPerformed(e);
  349.     }
  350.  
  351.     /**
  352.      * Handles the itemStateChanged event by invoking the
  353.      * itemStateChanged methods on listener-a and listener-b.
  354.      * @param e the item event
  355.      */
  356.     public void itemStateChanged(ItemEvent e) {
  357.         ((ItemListener)a).itemStateChanged(e);
  358.         ((ItemListener)b).itemStateChanged(e);
  359.     }
  360.  
  361.     /**
  362.      * Handles the adjustmentValueChanged event by invoking the
  363.      * adjustmentValueChanged methods on listener-a and listener-b.
  364.      * @param e the adjustment event
  365.      */
  366.     public void adjustmentValueChanged(AdjustmentEvent e) {
  367.         ((AdjustmentListener)a).adjustmentValueChanged(e);
  368.         ((AdjustmentListener)b).adjustmentValueChanged(e);
  369.     }
  370.     public void textValueChanged(TextEvent e) {
  371.         ((TextListener)a).textValueChanged(e);
  372.         ((TextListener)b).textValueChanged(e);
  373.     }
  374.  
  375.     /**
  376.      * Adds component-listener-a with component-listener-b and
  377.      * returns the resulting multicast listener.
  378.      * @param a component-listener-a
  379.      * @param b component-listener-b
  380.      */
  381.     public static ComponentListener add(ComponentListener a, ComponentListener b) {
  382.         return (ComponentListener)addInternal(a, b);
  383.     }
  384.  
  385.     /**
  386.      * Adds container-listener-a with container-listener-b and
  387.      * returns the resulting multicast listener.
  388.      * @param a container-listener-a
  389.      * @param b container-listener-b
  390.      */
  391.     public static ContainerListener add(ContainerListener a, ContainerListener b) {
  392.         return (ContainerListener)addInternal(a, b);
  393.     }
  394.  
  395.     /**
  396.      * Adds focus-listener-a with focus-listener-b and
  397.      * returns the resulting multicast listener.
  398.      * @param a focus-listener-a
  399.      * @param b focus-listener-b
  400.      */
  401.     public static FocusListener add(FocusListener a, FocusListener b) {
  402.         return (FocusListener)addInternal(a, b);
  403.     }
  404.  
  405.     /**
  406.      * Adds key-listener-a with key-listener-b and
  407.      * returns the resulting multicast listener.
  408.      * @param a key-listener-a
  409.      * @param b key-listener-b
  410.      */
  411.     public static KeyListener add(KeyListener a, KeyListener b) {
  412.         return (KeyListener)addInternal(a, b);
  413.     }
  414.  
  415.     /**
  416.      * Adds mouse-listener-a with mouse-listener-b and
  417.      * returns the resulting multicast listener.
  418.      * @param a mouse-listener-a
  419.      * @param b mouse-listener-b
  420.      */
  421.     public static MouseListener add(MouseListener a, MouseListener b) {
  422.         return (MouseListener)addInternal(a, b);
  423.     }
  424.  
  425.     /**
  426.      * Adds mouse-motion-listener-a with mouse-motion-listener-b and
  427.      * returns the resulting multicast listener.
  428.      * @param a mouse-motion-listener-a
  429.      * @param b mouse-motion-listener-b
  430.      */
  431.     public static MouseMotionListener add(MouseMotionListener a, MouseMotionListener b) {
  432.         return (MouseMotionListener)addInternal(a, b);
  433.     }
  434.  
  435.     /**
  436.      * Adds window-listener-a with window-listener-b and
  437.      * returns the resulting multicast listener.
  438.      * @param a window-listener-a
  439.      * @param b window-listener-b
  440.      */
  441.     public static WindowListener add(WindowListener a, WindowListener b) {
  442.         return (WindowListener)addInternal(a, b);
  443.     }
  444.  
  445.     /**
  446.      * Adds action-listener-a with action-listener-b and
  447.      * returns the resulting multicast listener.
  448.      * @param a action-listener-a
  449.      * @param b action-listener-b
  450.      */
  451.     public static ActionListener add(ActionListener a, ActionListener b) {
  452.         return (ActionListener)addInternal(a, b);
  453.     }
  454.  
  455.     /**
  456.      * Adds item-listener-a with item-listener-b and
  457.      * returns the resulting multicast listener.
  458.      * @param a item-listener-a
  459.      * @param b item-listener-b
  460.      */
  461.     public static ItemListener add(ItemListener a, ItemListener b) {
  462.         return (ItemListener)addInternal(a, b);
  463.     }
  464.  
  465.     /**
  466.      * Adds adjustment-listener-a with adjustment-listener-b and
  467.      * returns the resulting multicast listener.
  468.      * @param a adjustment-listener-a
  469.      * @param b adjustment-listener-b
  470.      */
  471.     public static AdjustmentListener add(AdjustmentListener a, AdjustmentListener b) {
  472.         return (AdjustmentListener)addInternal(a, b);
  473.     }
  474.     public static TextListener add(TextListener a, TextListener b) {
  475.         return (TextListener)addInternal(a, b);
  476.     }
  477.  
  478.     /**
  479.      * Removes the old component-listener from component-listener-l and
  480.      * returns the resulting multicast listener.
  481.      * @param l component-listener-l
  482.      * @param oldl the component-listener being removed
  483.      */
  484.     public static ComponentListener remove(ComponentListener l, ComponentListener oldl) {
  485.     return (ComponentListener) removeInternal(l, oldl);
  486.     }
  487.  
  488.     /**
  489.      * Removes the old container-listener from container-listener-l and
  490.      * returns the resulting multicast listener.
  491.      * @param l container-listener-l
  492.      * @param oldl the container-listener being removed
  493.      */
  494.     public static ContainerListener remove(ContainerListener l, ContainerListener oldl) {
  495.     return (ContainerListener) removeInternal(l, oldl);
  496.     }
  497.  
  498.     /**
  499.      * Removes the old focus-listener from focus-listener-l and
  500.      * returns the resulting multicast listener.
  501.      * @param l focus-listener-l
  502.      * @param oldl the focus-listener being removed
  503.      */
  504.     public static FocusListener remove(FocusListener l, FocusListener oldl) {
  505.     return (FocusListener) removeInternal(l, oldl);
  506.     }
  507.  
  508.     /**
  509.      * Removes the old key-listener from key-listener-l and
  510.      * returns the resulting multicast listener.
  511.      * @param l key-listener-l
  512.      * @param oldl the key-listener being removed
  513.      */
  514.     public static KeyListener remove(KeyListener l, KeyListener oldl) {
  515.     return (KeyListener) removeInternal(l, oldl);
  516.     }
  517.  
  518.     /**
  519.      * Removes the old mouse-listener from mouse-listener-l and
  520.      * returns the resulting multicast listener.
  521.      * @param l mouse-listener-l
  522.      * @param oldl the mouse-listener being removed
  523.      */
  524.     public static MouseListener remove(MouseListener l, MouseListener oldl) {
  525.     return (MouseListener) removeInternal(l, oldl);
  526.     }
  527.  
  528.     /**
  529.      * Removes the old mouse-motion-listener from mouse-motion-listener-l 
  530.      * and returns the resulting multicast listener.
  531.      * @param l mouse-motion-listener-l
  532.      * @param oldl the mouse-motion-listener being removed
  533.      */
  534.     public static MouseMotionListener remove(MouseMotionListener l, MouseMotionListener oldl) {
  535.     return (MouseMotionListener) removeInternal(l, oldl);
  536.     }
  537.  
  538.     /**
  539.      * Removes the old window-listener from window-listener-l and
  540.      * returns the resulting multicast listener.
  541.      * @param l window-listener-l
  542.      * @param oldl the window-listener being removed
  543.      */
  544.     public static WindowListener remove(WindowListener l, WindowListener oldl) {
  545.     return (WindowListener) removeInternal(l, oldl);
  546.     }
  547.  
  548.     /**
  549.      * Removes the old action-listener from action-listener-l and
  550.      * returns the resulting multicast listener.
  551.      * @param l action-listener-l
  552.      * @param oldl the action-listener being removed
  553.      */
  554.     public static ActionListener remove(ActionListener l, ActionListener oldl) {
  555.     return (ActionListener) removeInternal(l, oldl);
  556.     }
  557.  
  558.     /**
  559.      * Removes the old item-listener from item-listener-l and
  560.      * returns the resulting multicast listener.
  561.      * @param l item-listener-l
  562.      * @param oldl the item-listener being removed
  563.      */
  564.     public static ItemListener remove(ItemListener l, ItemListener oldl) {
  565.     return (ItemListener) removeInternal(l, oldl);
  566.     }
  567.  
  568.     /**
  569.      * Removes the old adjustment-listener from adjustment-listener-l and
  570.      * returns the resulting multicast listener.
  571.      * @param l adjustment-listener-l
  572.      * @param oldl the adjustment-listener being removed
  573.      */
  574.     public static AdjustmentListener remove(AdjustmentListener l, AdjustmentListener oldl) {
  575.     return (AdjustmentListener) removeInternal(l, oldl);
  576.     }
  577.     public static TextListener remove(TextListener l, TextListener oldl) {
  578.     return (TextListener) removeInternal(l, oldl);
  579.     }
  580.  
  581.     /** 
  582.      * Returns the resulting multicast listener from adding listener-a
  583.      * and listener-b together.  
  584.      * If listener-a is null, it returns listener-b;  
  585.      * If listener-b is null, it returns listener-a
  586.      * If neither are null, then it creates and returns
  587.      * a new AWTEventMulticaster instance which chains a with b.
  588.      * @param a event listener-a
  589.      * @param b event listener-b
  590.      */
  591.     protected static EventListener addInternal(EventListener a, EventListener b) {
  592.     if (a == null)  return b;
  593.     if (b == null)  return a;
  594.     return new AWTEventMulticaster(a, b);
  595.     }
  596.  
  597.     /** 
  598.      * Returns the resulting multicast listener after removing the
  599.      * old listener from listener-l.
  600.      * If listener-l equals the old listener OR listener-l is null, 
  601.      * returns null.
  602.      * Else if listener-l is an instance of AWTEventMulticaster, 
  603.      * then it removes the old listener from it.
  604.      * Else, returns listener l.
  605.      * @param l the listener being removed from
  606.      * @param oldl the listener being removed
  607.      */
  608.     protected static EventListener removeInternal(EventListener l, EventListener oldl) {
  609.     if (l == oldl || l == null) {
  610.         return null;
  611.     } else if (l instanceof AWTEventMulticaster) {
  612.         return ((AWTEventMulticaster)l).remove(oldl);
  613.     } else {
  614.         return l;        // it's not here
  615.     }
  616.     }
  617.       
  618.  
  619.     /* Serialization support.  
  620.      */
  621.  
  622.     protected void saveInternal(ObjectOutputStream s, String k) throws IOException {
  623.         if (a instanceof AWTEventMulticaster) {
  624.         ((AWTEventMulticaster)a).saveInternal(s, k);
  625.         }
  626.         else if (a instanceof Serializable) {
  627.             s.writeObject(k);
  628.             s.writeObject(a);
  629.         }
  630.         
  631.         if (b instanceof AWTEventMulticaster) {
  632.         ((AWTEventMulticaster)b).saveInternal(s, k);
  633.         }
  634.         else if (b instanceof Serializable) {
  635.             s.writeObject(k);
  636.             s.writeObject(b);
  637.         }
  638.     }
  639.  
  640.     protected static void save(ObjectOutputStream s, String k, EventListener l) throws IOException {
  641.       if (l == null) {
  642.           return;
  643.       } 
  644.       else if (l instanceof AWTEventMulticaster) {
  645.           ((AWTEventMulticaster)l).saveInternal(s, k);
  646.       }
  647.       else if (l instanceof Serializable) {
  648.            s.writeObject(k);
  649.            s.writeObject(l);
  650.       }
  651.     }
  652. }
  653.